package com.bidevalution.business.impl;

import com.bidevalution.business.context.BidType;
import com.bidevalution.business.context.FileType;
import com.bidevalution.business.context.StepType;
import com.bidevalution.business.service.ViewFileService;
import com.bidevalution.core.Common;
import com.bidevalution.dao.entity.*;
import com.bidevalution.dao.mapper.*;
import com.bidevalution.support.context.Constants;
import com.bidevalution.support.dto.TreeNodeDTO;
import com.qtp.core.util.OConvertUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author huyiqi
 * @date 2019/12/7
 */
@Service(value = "viewFileService")
public class ViewFileServiceImpl implements ViewFileService {

    private static final String PARAM_ID_PERF = "ProjPerf";
    private static final String PARAM_ID_MODULE = "Module";

    private static final String DOWNLOAD_SERVLET_NAME = "UploadedFile";
    private static final String BUCKET_NAME = "bucket";

    private static final String OTHER_ATTACHMENT_NAME_ZB = "招标文件";
    private static final String ZBWJ_NODE_ID = "ZBWJ";

    private static final String FORMAT_TREE_NODE_ID = "%s,%s";

    @Override
    public List<FileType> getFileTypes(String sectionId, String stepId, boolean isZb) {
        List<FileType> result = null;

        //技术标暗标的情况，查看投标文件，只能看技术标的，其他不能看
        if(isTechnology(stepId) && !isZb) {
            if(isHidden(sectionId)) {
                result = new ArrayList<>();
                result.add(FileType.TECHNOLOGY);
            }
        }
        if(result == null) {
            boolean needPerf = needPerf(sectionId);
            BeSectionInfo  sectionInfo = beSectionInfoMapper.getSectionInfoById(sectionId);
            if(sectionInfo != null) {
                String projectId = getProjectId(sectionId);
                int fileTypes = fileTypes(projectId);
                result = FileType.getFileTypeList(fileTypes, needPerf, isZb);
            }
        }

        return result;
    }

    @Override
    public List<TreeNodeDTO> getFileStructure(String sectionId, FileType fileType, String enterpriseId) {
        List<TreeNodeDTO> treeNodeList = null;
        //标段信息
        BeSectionInfo  sectionInfo = beSectionInfoMapper.getSectionInfoById(sectionId);
        if(sectionInfo != null) {
            //项目id
            String projectId = getProjectId(sectionId);
            //相应的结构
            List<FileStructure> structures = getStructs(projectId, fileType, sectionInfo, enterpriseId);
            if(structures != null && !structures.isEmpty()) {
                //组装树结构
                treeNodeList = buildTreeNode(structures);
            }
        }
        return treeNodeList;
    }

    @Override
    public List<FileInfo> getFileInfo(String projectId, String nodeId, String enterpriseId, FileType fileType) {
        List<FileInfo> fileInfos = getFileInfos(projectId, nodeId, enterpriseId, fileType);
        if(fileInfos != null) {
            for(FileInfo fileInfo:fileInfos) {
                String bucket = fileInfo.getProjectId();
                String businessId = fileInfo.getFileMd5();
                String filePath;
                if(ZBWJ_NODE_ID.equals(nodeId)) {
                    filePath = businessId;
                } else {
                    filePath = Common.spliceUrl(BUCKET_NAME, bucket, businessId);
                }
                fileInfo.setFilePath(filePath);
            }
        }
        return fileInfos;
    }

    @Override
    public List<BeSectionEnterprise> getSectionEntList(String sectionId, String stepId) {
        boolean isHidden = false;
        if(isTechnology(stepId)) {
            isHidden = isHidden(sectionId);
        }
        return viewFileMapper.getEnterpriseList(sectionId, isHidden);
    }

    /**
     * 查询是否需要业绩
     * @param sectionId 标段id
     * @return 返回是否需要业绩
     */
    private boolean needPerf(String sectionId) {
        String projPerf = getSectionParam(sectionId, PARAM_ID_PERF);
        return Constants.STR_YES.equals(projPerf);
    }

    /**
     * 获取标段的评审因素的相量
     * @param projectId 项目id
     * @return 返回评审因素的相量
     */
    private int fileTypes(String projectId) {
        String fileTypes = paramsMapper.getBeSectionParamsByCode(projectId, PARAM_ID_MODULE);
        return OConvertUtils.getInt(fileTypes, 0);
    }

    /**
     * 获取项目projectId
     * @param sectionId 标段id
     * @return 返回项目projectId
     */
    private String getProjectId(String sectionId) {
        String projectId = null;
        BeSectionInfo  sectionInfo = beSectionInfoMapper.getSectionInfoById(sectionId);
        if(sectionInfo != null) {
            projectId = sectionInfo.getTdProjectid();
        }
        return projectId;
    }

    /**
     * 获取结构列表
     * @param projectId 项目projectId
     * @param fileType 结构类型
     * @return 返回结构列表
     */
    private List<FileStructure> getStructs(String projectId, FileType fileType, BeSectionInfo  sectionInfo, String enterpriseId) {
        List<FileStructure> structures = null;
        switch (fileType) {
            case BUSINESS:
                structures = viewFileMapper.getBusinessStruct(projectId);
                break;
            case TECHNOLOGY:
                structures = viewFileMapper.getTechnologyStruct(projectId);
                break;
            case COMPOSITE:
                structures = viewFileMapper.getCompositeStruct(projectId);
                break;
            case PERFORMANCE:
                structures = viewFileMapper.getQualificateStruct(projectId);
                break;
            case BID_FILE:
                structures = viewFileMapper.getTbOtherStruct(projectId, enterpriseId);
                break;
            case TENDER_FILE:
                structures = getTenderFileStruct(projectId);
                break;
            default:
                break;
        }
        return structures;
    }

    private List<FileInfo> getFileInfos(String projectId, String nodeId, String enterpriseId, FileType fileType) {
        List<FileInfo> fileInfos = null;
        switch (fileType) {
            case BUSINESS:
                if(StringUtils.isBlank(enterpriseId)) {
                    fileInfos = viewFileMapper.getZbBusinessFiles(projectId, nodeId);
                } else {
                    fileInfos = viewFileMapper.getTbBusinessFiles(projectId, nodeId, enterpriseId);
                }
                break;
            case TECHNOLOGY:
                fileInfos = viewFileMapper.getTbTechnologyFiles(projectId, nodeId, enterpriseId);
                break;
            case COMPOSITE:
                fileInfos = viewFileMapper.getTbCompositeFiles(projectId, nodeId, enterpriseId);
                break;
            case PERFORMANCE:
                fileInfos = viewFileMapper.getTbQualificateFiles(projectId, nodeId, enterpriseId);
                break;
            case BID_FILE:
                fileInfos = viewFileMapper.getTbOtherFiles(projectId, enterpriseId, nodeId);
                break;
            case TENDER_FILE:
                fileInfos = getTenderFileList(projectId, nodeId);
                break;
            default:
                break;
        }
        return fileInfos;
    }

    /**
     * 招标其他附件
     * @param projectId 项目id
     * @return 返回招标其他附件的结构
     */
    private List<FileStructure> getTenderFileStruct(String projectId) {
        List<FileStructure> list = viewFileMapper.getZbOtherStruct(projectId);

        FileStructure zbwj = new FileStructure();
        zbwj.setNodeId(ZBWJ_NODE_ID);
        zbwj.setParentId("");
        zbwj.setProjectId(projectId);
        zbwj.setName(OTHER_ATTACHMENT_NAME_ZB);

        list.add(0, zbwj);
        return list;
    }

    private List<FileInfo> getTenderFileList(String projectId, String nodeId) {
        List<FileInfo> list;
        if(ZBWJ_NODE_ID.equals(nodeId)) {
            BeSectionInfo sectionInfo = beSectionInfoMapper.getSectionInfoByProjId(projectId);
            String fileMd5 = sectionInfo.getTenderFileMd5();

            FileInfo fileInfo = new FileInfo();
            fileInfo.setFileName(OTHER_ATTACHMENT_NAME_ZB);
            fileInfo.setFileMd5(fileMd5);
            fileInfo.setProjectId(projectId);

            list = new ArrayList<>();
            list.add(fileInfo);
        } else {
            list = viewFileMapper.getZbOtherFiles(projectId, nodeId);
        }
        return list;
    }

    /**
     * 组装结构树
     * @param structures 结构列表
     * @return 返回结构树
     */
    private List<TreeNodeDTO> buildTreeNode(List<FileStructure> structures) {
        List<TreeNodeDTO> tree = new ArrayList<>();
        Map<String, TreeNodeDTO> treeNodeMapping = new HashMap<>(structures.size());

        //将结构id和结构的对应关系放到map中
        for(FileStructure fileStructure:structures) {
            TreeNodeDTO treeNode = new TreeNodeDTO();
            List<TreeNodeDTO> children = new ArrayList<>();

            String projectId = fileStructure.getProjectId();
            String nodeId = fileStructure.getNodeId();
            treeNode.setId(String.format(FORMAT_TREE_NODE_ID, projectId, nodeId));
            treeNode.setLabel(fileStructure.getName());
            treeNode.setParentId(fileStructure.getParentId());
            treeNode.setChildren(children);

            treeNodeMapping.put(nodeId, treeNode);
        }

        //组装父子关系
        for(FileStructure fileStructure:structures) {
            TreeNodeDTO treeNode = treeNodeMapping.get(fileStructure.getNodeId());
            String parentId = treeNode.getParentId();
            if(treeNodeMapping.containsKey(parentId)) {
                TreeNodeDTO parentNode = treeNodeMapping.get(parentId);
                List<TreeNodeDTO> children = parentNode.getChildren();
                children.add(treeNode);
            } else {
                tree.add(treeNode);
            }
        }

        return tree;
    }

    /**
     * 获取指定的标段参数值
     * @param sectionId 标段id
     * @param paramId 参数类型
     * @return 返回参数值，没有返回空字符串
     */
    private String getSectionParam(String sectionId, String paramId) {
        String value = "";
        BeSectionParameterKey key = new BeSectionParameterKey();
        key.setParamId(paramId);
        key.setSectionId(sectionId);
        BeSectionParameter param = parameterMapper.selectByPrimaryKey(key);
        if(param != null) {
            value = param.getParamValue();
        }
        return value;
    }

    private boolean isHidden(String sectionId) {
        String projectId = getProjectId(sectionId);
        TdAuditMethod tdAuditMethod = tdAuditMethodMapper.getAuditMethod(projectId);
        return tdAuditMethod != null && BidType.HIDDEN.getCode().equals(tdAuditMethod.getAumeIsBidHide());
    }

    private boolean isTechnology(String stepId) {
        if(StringUtils.isBlank(stepId)) {
            return false;
        }
        BeSectionStep sectionStep = beSectionStepMapper.selectByPrimaryKey(stepId);
        String stepType = sectionStep.getStepType();
        return StepType.Technology.getCode().equals(stepType);
    }

    @Autowired(required = false)
    private BeSectionParameterMapper parameterMapper;
    @Autowired(required = false)
    private BeSectionParamsMapper paramsMapper;
    @Autowired(required = false)
    private ViewFileMapper viewFileMapper;
    @Autowired(required = false)
    private BeSectionInfoMapper beSectionInfoMapper;
    @Autowired(required = false)
    private BeSectionStepMapper beSectionStepMapper;
    @Autowired(required = false)
    private TdAuditMethodMapper tdAuditMethodMapper;
    @Value("${download.file.path}")
    private String downloadFilePath;
}
